﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Windows.Media;

internal class MyMediaStreamSource : MediaStreamSource
{
    private MediaStreamDescription _audioDesc;
    internal long _currentPosition;
    internal long _currentTimeStamp;
    private Dictionary<MediaSampleAttributeKeys, string> _emptySampleDict = new Dictionary<MediaSampleAttributeKeys, string>();
    internal long _startPosition;
    private FixedMemoryStream _stream;
    internal WaveFormatEx _waveFormat;
    private const int BitsPerSample = 0x10;
    private const int ByteRate = 0x2b110;
    private const int ChannelCount = 2;
    private MediaStreamSample msSamp;
    private bool PROCEED;
    private static Stream streamSave;
    private const int SampleRate = 0xac44;

    internal MyMediaStreamSource()
    {
        base.AudioBufferLength=20;
        this._waveFormat = new WaveFormatEx();
        this._waveFormat.BitsPerSample = 0x10;
        this._waveFormat.AvgBytesPerSec = 0x2b110;
        this._waveFormat.Channels = 2;
        this._waveFormat.BlockAlign = 4;
        this._waveFormat.ext = null;
        this._waveFormat.FormatTag = 1;
        this._waveFormat.SamplesPerSec = 0xac44;
        this._waveFormat.Size = 0;
        this._waveFormat.ValidateWaveFormat();
        this._stream = new FixedMemoryStream(100000);
    }

    protected override void CloseMedia()
    {
        this._startPosition = this._currentPosition = 0L;
        this._audioDesc = null;
    }

    protected override void GetDiagnosticAsync(MediaStreamSourceDiagnosticKind diagnosticKind)
    {
        throw new NotImplementedException();
    }

    protected override void GetSampleAsync(MediaStreamType mediaStreamType)
    {
        this.PROCEED = true;
    }

    protected override void OpenMediaAsync()
    {
        this._startPosition = this._currentPosition = 0L;
        Dictionary<MediaStreamAttributeKeys, string> dictionary = new Dictionary<MediaStreamAttributeKeys, string>();
        Dictionary<MediaSourceAttributesKeys, string> dictionary2 = new Dictionary<MediaSourceAttributesKeys, string>();
        List<MediaStreamDescription> list = new List<MediaStreamDescription>();
        dictionary[0] = this._waveFormat.ToHexString();
        MediaStreamDescription description = new MediaStreamDescription(0, dictionary);
        this._audioDesc = description;
        list.Add(this._audioDesc);
        dictionary2[MediaSourceAttributesKeys.Duration] = TimeSpan.FromMinutes(0.0).Ticks.ToString(CultureInfo.InvariantCulture);
        dictionary2[MediaSourceAttributesKeys.CanSeek] = false.ToString();
        base.ReportOpenMediaCompleted(dictionary2, list);
    }

    protected override void SeekAsync(long seekToTime)
    {
        base.ReportSeekCompleted(seekToTime);
    }

    protected override void SwitchMediaStreamAsync(MediaStreamDescription mediaStreamDescription)
    {
        throw new NotImplementedException();
    }

    private byte[] bufferdrop = null;
    private int dropcount = 0;

    internal void write(byte[] bytes, int blaa, int count)
    {
        bufferdrop = new byte[count];
        Array.Copy(bytes, bufferdrop, count);
    }

    internal void WriteSound()
    {
        if (bufferdrop != null)
        {
            this._stream.Write(bufferdrop, 0, bufferdrop.Length);
            this.msSamp = new MediaStreamSample(this._audioDesc,
                                                this._stream,
                                                this._currentPosition,
                                                (long)bufferdrop.Length,
                                                this._currentTimeStamp,
                                                this._emptySampleDict);
            if (this.PROCEED)
            {
                base.ReportGetSampleCompleted(this.msSamp);
                this.PROCEED = false;
            }
            this._currentPosition += bufferdrop.Length;
            this._currentTimeStamp += this._waveFormat.AudioDurationFromBufferSize((uint)bufferdrop.Length);
        }

    }


    private void WriteHeader()
    {
        if (streamSave != null)
        {
            byte[] fmtHeader = _waveFormat.ToByteArray(streamSave);
            long pos = streamSave.Position;
            streamSave.Seek(0, SeekOrigin.Begin);
            streamSave.Write(fmtHeader, 0, fmtHeader.Length);
            streamSave.Seek(pos, SeekOrigin.Begin);
            streamSave.Flush();
        }
    }

    internal void SetSaveStream(Stream stream)
    {
        streamSave = stream;
    }

}

